package main

import "fmt"

// defer经典案例
// Go语言中函数的return不是原子操作，在底层是分位两步来执行
// 第一步: 返回赋值
// defer
// 第二步: 真正RET返回
// 函数中如果存在defer，那么defer执行的时机是在第一步和第二步之间

func f1() int {
	x := 5
	defer func() {
		x++ // 修改的是x不是返回值 x已经被声明为5了
		// 第一步 返回值赋值
		// 第二步 真正的RET返回
	}()
	return x
}
func f2() (x int) {
	// 第一步 返回值是x
	// 第二步 defer x 赋值6
	// 第三步 返回 x 以经变成6了
	defer func() {
		x++
	}()
	return 5
}
func f3() (y int) {
	// 第一步: 返回赋值
	// defer
	// 第二步: 真正RET返回
	x := 5
	defer func() {
		x++
	}()
	return x // 返回值 = y = x = 5
}
func f4() (x int) {
	defer func(x int) {
		x++ // 改变的是函数中的副本
	}(x) // 函数传参传的是copy
	return 5
}
func f5() (x int) {
	z := 5
	defer func() {
		z++
	}()
	return z
}
func main() {
	fmt.Println(f1())
	fmt.Println(f2())
	fmt.Println(f3())
	fmt.Println(f4())
	fmt.Println(f5())
}
